﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.Common;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using JYH.Data;
using JYH.DataAccess;
using JYH.Framework;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace JYH.DataAccess
{

    /// <summary>
    /// 业务基础类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class BusinessBase<T> where T : class, new()
    {
        private string _sqlSelect = "";
        /// <summary>
        /// 标准查询SQL指令
        /// </summary>
        public string SqlSelect
        {
            get
            {
                return _sqlSelect;
            }
            set
            {
                _sqlSelect = value;
            }
        }
        /// <summary>
        /// 数据库链接对象
        /// </summary>
        public Database myDataBase { get; set; }= DB.myDatabase;
       
        /// <summary>
        /// 保存(新增/修改)
        /// </summary>
        /// <param name="t">实体类</param>
        /// <param name="id">主键值</param>
        /// <param name="Msg">反馈信息</param>
        /// <returns></returns>
        public virtual bool Save(T t,string id, out string Msg)
        {
            Msg = string.Empty;
            try
            {
                if (myDataBase == null)
                {
                    myDataBase = DB.D("DBCONN");
                }
                return DA<T>.Save(t, id);
            }
            catch (Exception ex)
            {
                Msg = ex.ToString();
                return false;
            }
            
        }
        /// <summary>
        /// 保存
        /// </summary>
        /// <typeparam name="T">实体类</typeparam>
        /// <param name="Json">Json数据</param>
        /// <param name="Msg">反馈信息</param>
        /// <returns></returns>
        public virtual bool Save( string Json, string id, out string Msg)
        {
            Msg = string.Empty;
            try
            {
                if (myDataBase == null)
                {
                    myDataBase = DB.D("DBCONN");
                }
                T t = ConvertJson<T>.DeserializeJsonToObject(Json);
                return DA<T>.Save(t, id);
            }
            catch (Exception ex)
            {
                Msg = ex.ToString();
                return false;
            }

        }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="t">实体类</param>
        /// <param name="Msg">反馈信息</param>
        /// <returns></returns>
        public virtual bool Delete(T t, out string Msg)
        {
            Msg = string.Empty;
            try
            {
                if (myDataBase == null)
                {
                    myDataBase = DB.D("DBCONN");
                }
                List<T> list = new List<T>();
                list.Add(t);
                return DA<T>.Delete(list);
            }
            catch (Exception ex)
            {
                Msg = ex.ToString();
                return false;
            }

        }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id">主键值</param>
        /// <param name="Msg">反馈信息</param>
        /// <returns></returns>
        public virtual bool Delete(string id, out string Msg)
        {
            Msg = string.Empty;
            try
            {
                if (myDataBase == null)
                {
                    myDataBase = DB.D("DBCONN");
                }
                List<T> list = new List<T>();
                T t = DA<T>.FetchSingleById(id);
                if(t!=null)
                list.Add(t);
                return DA<T>.Delete(list);
            }
            catch (Exception ex)
            {
                Msg = ex.ToString();
                return false;
            }

        }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="list">实体类集合</param>
        /// <param name="Msg">反馈</param>
        /// <returns></returns>
        public virtual bool Delete( List<T> list, out string Msg)
        {
            Msg = string.Empty;
            try
            {
                if (myDataBase == null)
                {
                    myDataBase = DB.D("DBCONN");
                }
                return DA<T>.Delete(list);
            }
            catch (Exception ex)
            {
                Msg = ex.ToString();
                return false;
            }

        }
        /// <summary>
        /// 获取单个实体类
        /// </summary>
        /// <param name="sqlWhere">查询条件</param>
        /// <returns></returns>
        public virtual T GetSingeModel(Sql sqlWhere)
        {
            if (myDataBase == null)
            {
                myDataBase = DB.D("DBCONN");
            }
            Sql sql = new Sql();
            if (!string.IsNullOrEmpty(SqlSelect))
                sql.Append(SqlSelect);
            sql.Append(sqlWhere.SQL);
            return DA<T>.FetchSingle(sql);
        }
        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="pageIndex">起始页</param>
        /// <param name="pageSize">每页数量</param>
        /// <param name="whereSql">查询条件</param>
        /// <param name="total">记录总数</param>
        /// <param name="Msg">反馈信息</param>
        /// <param name="OrderBy">排序字段</param>
        /// <returns>实体类集合</returns>
        public virtual List<T> PagedQuery(long pageIndex, long pageSize, Sql whereSql , out long total, out string Msg, params object[] OrderBy)
        {
            Msg = string.Empty;
            Sql sql = new Sql();
            if(!string.IsNullOrEmpty(SqlSelect))
            sql.Append(SqlSelect);
            sql.Append(whereSql);
            if(OrderBy != null && OrderBy.Length>0)
            sql.OrderBy(OrderBy[0]);
            try
            {
                if (myDataBase != null)
                {
                    myDataBase = DB.D("DBCONN");
                }
                return DA<T>.PagedQuery(pageIndex, pageSize, sql, out total);          
            }
            catch (Exception ex)
            {
                Msg = ex.ToString();
                total = -1;
                return null;
            }
        }


        public virtual List<T> PagedQuery(Sql sql, long pageIndex, long pageSize,  out long total, out string Msg, params object[] OrderBy)
        {
            Msg = string.Empty;     
            if (OrderBy != null && OrderBy.Length > 0)
                sql.OrderBy(OrderBy[0]);
            try
            {
                if (myDataBase != null)
                {
                    myDataBase = DB.D("DBCONN");
                }
                return DA<T>.PagedQuery(pageIndex, pageSize, sql, out total);
            }
            catch (Exception ex)
            {
                Msg = ex.ToString();
                total = -1;
                return null;
            }
        }
        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="whereSql">查询条件</param>
        /// <param name="Msg">反馈信息</param>
        /// <param name="OrderBy">排序字段</param>
        /// <returns>实体类集合</returns>
        public virtual List<T> NotPagedQuery( Sql whereSql, out string Msg, params object[] OrderBy)
        {
            Msg = string.Empty;
            Sql sql = new Sql();
            if (!string.IsNullOrEmpty(SqlSelect))
                sql.Append(SqlSelect);
            sql.Append(whereSql);
            if (OrderBy != null && OrderBy.Length > 0)
                sql.OrderBy(OrderBy[0]);
            try
            {
                if (myDataBase != null)
                {
                    myDataBase = DB.D("DBCONN");
                }
                return DA<T>.Fetch( sql);
            }
            catch (Exception ex)
            {
                Msg = ex.ToString();
                return null;
            }
        }
        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="pageIndex">起始页</param>
        /// <param name="pageSize">每页数量</param>
        /// <param name="whereSql">查询条件</param>
        /// <param name="total">记录总数</param>
        /// <param name="Msg">反馈信息</param>
        /// <param name="OrderBy">排序字段</param>
        /// <returns>Dataset集合</returns>
        public virtual DataSet Query(long pageIndex, long pageSize, Sql whereSql, out long total, out string Msg, params object[] OrderBy)
        {
            Msg = string.Empty;
            Sql sql = new Sql();
            if (!string.IsNullOrEmpty(SqlSelect))
                sql.Append(SqlSelect);
            sql.Append(whereSql);
            if (OrderBy != null && OrderBy.Length > 0)
                sql.OrderBy(OrderBy[0]);
            try
            {
                if (myDataBase != null)
                {
                    myDataBase = DB.D("DBCONN");
                }
                List<T> list= DA<T>.PagedQuery(pageIndex, pageSize, sql, out total);
                DataSet ds= ConvertHelper.JsonToDataSet(ConvertJson<T>.ListToJson(list));
                return ds;
            }
            catch (Exception ex)
            {
                Msg = ex.ToString();
                total = -1;
                return null;
            }
        }
        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="whereSql">查询条件</param>
        /// <param name="Msg">反馈信息</param>
        /// <param name="OrderBy">排序字段</param>
        /// <returns>Dataset集合</returns>
        public virtual DataSet Query(Sql whereSql,  out string Msg, params object[] OrderBy)
        {
            Msg = string.Empty;
            Sql sql = new Sql();
            if (!string.IsNullOrEmpty(SqlSelect))
                sql.Append(SqlSelect);
            sql.Append(whereSql);
            if (OrderBy != null && OrderBy.Length > 0)
                sql.OrderBy(OrderBy[0]);
            try
            {
                if (myDataBase != null)
                {
                    myDataBase = DB.D("DBCONN");
                }
                List<T> list = DA<T>.Fetch(sql);
                DataSet ds = ConvertHelper.JsonToDataSet(ConvertJson<T>.ListToJson(list));
                return ds;
            }
            catch (Exception ex)
            {
                Msg = ex.ToString();
                return null;
            }
        }
        /// <summary>
        /// 保存
        /// </summary>
        /// <param name="db">数据库对象</param>
        /// <param name="t">实体类</param>
        /// <param name="id">主键值</param>
        /// <param name="Msg">反馈信息</param>
        /// <returns></returns>
        public virtual bool Save(ref Database db, T t, string id, out string Msg)
        {
            Msg = string.Empty;
            try
            {
              
                var pd = JYHData.ForType(t.GetType());
                T obj = db.SingleOrDefault<T>("WHERE " + pd.TableInfo.PrimaryKey + "=@0", id);
                if (obj==null)
                {
                    db.Insert(t);
                    
                }
                else
                {
                    db.Update(t);
                  
                }
                return true;
            }
            catch (Exception ex)
            {
                Msg = ex.ToString();
                return false;
            }

        }
        /// <summary>
        /// 保存 
        /// </summary>
        /// <param name="db">数据库对象</param>
        /// <param name="Json">实体类JSON数据</param>
        /// <param name="id">主键ID值</param>
        /// <param name="Msg">反馈信息</param>
        /// <returns></returns>
        public virtual bool Save(ref Database db, string Json, string id, out string Msg)
        {
            Msg = string.Empty;
            try
            {
               
                T t = ConvertJson<T>.DeserializeJsonToObject(Json);
                
                var pd = JYHData.ForType(t.GetType());
                T obj = db.SingleOrDefault<T>("WHERE " + pd.TableInfo.PrimaryKey + "=@0", id);
                if (obj == null)
                {
                    db.Insert(t);

                }
                else
                {
                    db.Update(t);

                }
                return true;
            }
            catch (Exception ex)
            {
                Msg = ex.ToString();
                return false;
            }

        }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="db">数据库对象</param>
        /// <param name="t">实体类</param>
        /// <param name="Msg">反馈</param>
        /// <returns></returns>
        public virtual bool Delete(ref Database db, T t, out string Msg)
        {
            Msg = string.Empty;
            try
            {
                
                db.Delete(t);
                return true;
            }
            catch (Exception ex)
            {
                Msg = ex.ToString();
                return false;
            }

        }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="db">数据库对象</param>
        /// <param name="list">实体类集合</param>
        /// <param name="Msg">反馈</param>
        /// <returns></returns>
        public virtual bool Delete(ref Database db, List<T> list, out string Msg)
        {
            Msg = string.Empty;
            try
            {
               
                foreach (T t in list)
                {
                    if (db.Delete(t) < 0)
                    {
                        return false;
                    }
                }
                return true;
            }
            catch (Exception ex)
            {
                Msg = ex.ToString();
                return false;
            }

        }
        /// <summary>
        /// 获取单个对象
        /// </summary>
        /// <param name="db">数据库对象</param>
        /// <param name="sqlWhere">查询条件</param>
        /// <returns></returns>
        public virtual T GetSingeModel(ref Database db, Sql sqlWhere)
        {
            Sql sql = new Sql();
            if (!string.IsNullOrEmpty(SqlSelect))
                sql.Append(SqlSelect);
            sql.Append(sqlWhere);
            return db.FirstOrDefault<T>(sql);
        }
        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="pageIndex">起始页</param>
        /// <param name="pageSize">每页数量</param>
        /// <param name="whereSql">查询条件</param>
        /// <param name="total">记录总数</param>
        /// <param name="Msg">反馈信息</param>
        /// <param name="OrderBy">排序字段</param>
        /// <param name="db">数据库对象</param>
        /// <returns>实体类集合</returns>
        public virtual List<T> PagedQuery(ref Database db, long pageIndex, long pageSize, Sql whereSql, out long total, out string Msg, params object[] OrderBy)
        {
            Msg = string.Empty;
            Sql sql = new Sql();
            if (!string.IsNullOrEmpty(SqlSelect))
                sql.Append(SqlSelect);
            sql.Append(whereSql);
            if (OrderBy != null && OrderBy.Length > 0)
                sql.OrderBy(OrderBy[0]);
            try
            {
                var result = db.Page<T>(pageIndex, pageSize, sql);
                total = result.TotalItems;
                return result.Items;
                //return db.Page<T>(pageIndex, pageSize, sql, out total);
            }
            catch (Exception ex)
            {
                Msg = ex.ToString();
                total = -1;
                return null;
            }
        }
        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="whereSql">查询条件</param>
        /// <param name="Msg">反馈信息</param>
        /// <param name="OrderBy">排序字段</param>
        /// <param name="db">数据库对象</param>
        /// <returns>实体类集合</returns>
        public virtual List<T> NotPagedQuery(ref Database db, Sql whereSql, out string Msg, params object[] OrderBy)
        {
            Msg = string.Empty;
            Sql sql = new Sql();
            if (!string.IsNullOrEmpty(SqlSelect))
                sql.Append(SqlSelect);
            sql.Append(whereSql);
            if (OrderBy != null && OrderBy.Length > 0)
                sql.OrderBy(OrderBy[0]);
            try
            {
                return db.Fetch<T>(sql);
            }
            catch (Exception ex)
            {
                Msg = ex.ToString();
                return null;
            }
        }
        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="pageIndex">起始页</param>
        /// <param name="db">数据库对象</param>
        /// <param name="pageSize">每页数量</param>
        /// <param name="whereSql">查询条件</param>
        /// <param name="total">记录总数</param>
        /// <param name="Msg">反馈信息</param>
        /// <param name="OrderBy">排序字段</param>
        /// <returns>Dataset集合</returns>
        public virtual DataSet Query(ref Database db, long pageIndex, long pageSize, Sql whereSql, out long total, out string Msg, params object[] OrderBy)
        {
            Msg = string.Empty;
            Sql sql = new Sql();
            if (!string.IsNullOrEmpty(SqlSelect))
                sql.Append(SqlSelect);
            sql.Append(whereSql);
            if (OrderBy != null && OrderBy.Length > 0)
                sql.OrderBy(OrderBy[0]);
            try
            {
                DataSet ds = new DataSet();
               
                var result = db.Page<T>(pageIndex, pageSize, sql);
                total = result.TotalItems;
                 ds = ConvertHelper.JsonToDataSet(ConvertJson<T>.ListToJson(result.Items));
                return ds;
            }
            catch (Exception ex)
            {
                Msg = ex.ToString();
                total = -1;
                return null;
            }
        }
        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="whereSql">查询条件</param>
        /// <param name="Msg">反馈信息</param>
        /// <param name="OrderBy">排序字段</param>
        /// <param name="db">数据库对象</param>
        /// <returns>Dataset集合</returns>
        public virtual DataSet Query(ref Database db, Sql whereSql, out string Msg, params object[] OrderBy)
        {
            Msg = string.Empty;
            Sql sql = new Sql();
            if (!string.IsNullOrEmpty(SqlSelect))
                sql.Append(SqlSelect);
            sql.Append(whereSql);
            if (OrderBy != null&&OrderBy.Length > 0 )
                sql.OrderBy(OrderBy[0]);
            try
            {
                DataSet ds = new DataSet();
                db.Fill(ds, sql.SQL, null);
                return ds;
            }
            catch (Exception ex)
            {
                Msg = ex.ToString();
                return null;
            }
        }

        /// <summary>
        /// Json赋值Model对象
        /// </summary>
        /// <param name="Json">Json数据</param>
        /// <param name="t">Model对象</param>
        /// <returns></returns>
        public virtual T JsonSetObject(string Json, T t)
        {
            var ss = ConvertJson<Dictionary<string, object>>.DeserializeJsonToObject(Json);
            ModelBase model = new ModelBase(ss);
            List<string> names = model.GetDynamicMemberNames().ToList();
            JObject jo = (JObject)JsonConvert.DeserializeObject(Json);
            PropertyInfo[] fs = t.GetType().GetProperties();
            for (int i = 0; i < names.Count; i++)
            {
                object en = null;
                string val = jo.GetValue(names[i]).ToString();
                foreach (PropertyInfo ts in fs)
                {
                    

                    if (names[i] == ts.Name)
                    {
                        object defaultVal;
                        if (ts.PropertyType.Name.Equals("String"))
                            defaultVal = "";
                        else if (ts.PropertyType.Name.Equals("Boolean"))
                        {
                            defaultVal = false;
                            val = (val.Equals("1") || val.Equals("on")).ToString();
                        }
                        else if (ts.PropertyType.Name.Equals("Decimal"))
                            defaultVal = 0M;
                        else
                            defaultVal = 0;

                        if (!ts.PropertyType.IsGenericType)
                            en = string.IsNullOrEmpty(val) ? defaultVal : Convert.ChangeType(val, ts.PropertyType);
                        else
                        {
                            Type genericTypeDefinition = ts.PropertyType.GetGenericTypeDefinition();
                            if (genericTypeDefinition == typeof(Nullable<>))
                                en = string.IsNullOrEmpty(val) ? defaultVal : Convert.ChangeType(val, Nullable.GetUnderlyingType(ts.PropertyType));
                        }

                        ts.SetValue(t, en,null);
                    }
                }


            }
            return t;
        }

        /// <summary>
        /// EasyUI DataGrid 数据JOSN格式
        /// </summary>
        /// <param name="list">List对象</param>
        /// <param name="Total">总记录数</param>
        /// <returns></returns>
        public virtual string ListToEasyUIJson(List<T> list,long Total)
        {
            var json = ConvertJson<T>.ListToJson(list);
            var s = "{\"total\":" + Total + ",\"rows\":" + json + "}";
            return s;
        }
    }
}
